/**
 * 初始参数
 * @param maxAge 最大生存时间 默认为5 单位分钟,
 * @param codeLength 生成代码长度 默认为6
 * @param expireTime 可再次发送短信的时间
 *
 */
interface IParms{
  age: number;
  length: number;
  expireTime: number;
  [props: string]: any;
}

const store = {} as IAnyObject, numbers = '0123456789'
let maxAge = 5, codeLength = 6, expireTime = 1;
 
 /**
  * 生成指定长度的随机数字
  * @param length 指定长度
  * @returns {string} 指定长度的数字字符串
  */
const random = (length: number) => {
  length || (length = 4)
  let chars = ''
  let result = ''

  chars += numbers

  while (length > 0) {
    length--
    result += chars[Math.floor(Math.random() * chars.length)]
  }
  return result
}
 
const codeUtil = {
  /**
  * 设置基础参数
  * @param options = {
  *      age: 最大生存时间 默认为5 单位分钟,
  *      length: 生成代码长度 默认为4
  *  }
  */
  setOptions: (options: IParms) => {
    if (options.age && options.age > 0) {
      maxAge = options.age
    }
    if (options.length && options.length > 0) {
      codeLength = options.length
    }
    if (options.expireTime && options.expireTime > 0 && expireTime < maxAge) {
      expireTime = options.length
    }
  },

  /**
  * 获取随机生成的代码
  * @param phone 获取验证码的手机号码
  * @returns {string} 生成的代码
  */
  getCode: (phone: string) => {
    phone = String(phone)
    const code = random(codeLength)

    store[phone] = {
      code,
      createTime: Date.now(),
    }

    // 有计时器的话应该先去掉之前的计时器
    if (store[phone].timer) {
      clearTimeout(store[phone].timer);
    }
    store[phone].timer = setTimeout(() => {
      delete store[phone]
    }, maxAge * 60 * 1000)

    return code;
  },

  /**
  * 时间是否过期
  * @param phone 获取验证码的手机号码
  * @returns {boolean}} 验证结果
  */
   verifyTime: (phone: string) => {
    phone = String(phone);
    if (store[phone] && store[phone].createTime) {
      return Date.now() - store[phone].createTime >= expireTime * 60 * 1000;
    }
    // 都没有这个手机号就直接返回true
    return true;
  },

  /**
  * 验证代码是否正确
  * @param phone 需要验证的手机号码
  * @param code 需要验证的手机号码对应的代码
  * @returns {boolean} 验证结果
  */
  verifyCode: (phone: string, code: string) => {
    code = String(code)
    phone = String(phone)
    if (store[phone] && store[phone].code === code) {
      delete store[phone]
      return true
    } else {
      return false
    }
  }
}

export default codeUtil;
